#ifndef _UTILEX_THREAD_HPP_
#define _UTILEX_THREAD_HPP_

#include <crt_util.h>

#ifdef __cplusplus

class CThread
{
public:
    CThread()
    {
        thread = INVALID_HANDLE_VALUE;
        m_State = S_ERROR;
    }
    virtual ~CThread() { }
    int Start_Thread()
    {
        rc_error(thread == INVALID_HANDLE_VALUE, S_ERROR);
        this->Thread_Init();
        int rc = _thread_create(&thread, CThread::thread_proc, this);
        rc_error(rc == S_SUCCESS, S_ERROR) this->WaitSem();
        return S_SUCCESS;
    }

    int Stop_Thread()
    {
        rc_error(thread != INVALID_HANDLE_VALUE, S_ERROR);
        this->Thread_UnInit();
        _thread_join(&thread);
        return S_SUCCESS;
    }

    int PostSem()
    {
        rc_error(thread != INVALID_HANDLE_VALUE, S_ERROR);
        m_Sem.Post();
        return S_SUCCESS;
    }
    int WaitSem()
    {
        rc_error(thread != INVALID_HANDLE_VALUE, S_ERROR);
        m_Sem.Wait();
        return S_SUCCESS;
    }
    static void thread_proc(void* pthis)
    {
        CThread* p = static_cast<CThread*>(pthis);
        if (p) {
            p->PostSem();
            p->Thread_Run();
        }
    }

protected:
    std_method(Thread_Init)() PURE;
    std_method(Thread_Run)() PURE;
    std_method(Thread_UnInit)() PURE;

protected:
    _thread_t thread;
    CSemHandle m_Sem;
    UINT m_State;
};

#endif

#endif
